from sys import argv
from OpenGL.GL import *
from OpenGL.GLU import *
from OpenGL.GLUT import *

class MyPyOpenGLTest:
    def __init__(self, width=640, height=480, title='三次Bezier曲面'):
        glutInit(len(argv), argv)
        glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH)
        glutInitWindowSize(width, height)
        glutInitWindowPosition(350, 200)
        self.window = glutCreateWindow(title.encode('gbk'))
        glutDisplayFunc(self.draw)
        glutIdleFunc(self.draw)
        glutKeyboardFunc(self.key_press)
        
        glClearColor(1, 1, 1, 1)
        glEnable(GL_DEPTH_TEST)
        glShadeModel(GL_SMOOTH)
        glEnable(GL_POINT_SMOOTH)
        glEnable(GL_LINE_SMOOTH)
        glEnable(GL_POLYGON_SMOOTH)
        glHint(GL_POINT_SMOOTH_HINT,GL_NICEST)
        glHint(GL_LINE_SMOOTH_HINT,GL_NICEST)
        glHint(GL_POLYGON_SMOOTH_HINT,GL_FASTEST)

        glMatrixMode(GL_PROJECTION)
        glLoadIdentity()
        glOrtho(-5, 5, -5, 5, -5, 5)
        # 指定三次贝塞尔曲面的16个控制点坐标
        self.control_points = (
            ((-2,-2,-4), (-1,-2,4), (1,-2,-4), (2,-2,-4)),
            ((-2,-1,-1), (-1,-1,-1), (1,-1,-1), (2,-1,-1)),
            ((-2,1,1), (-1,1,1), (1,1,1), (2,1,1)),
            ((-2,2,4), (-1,2,-4), (1,2,4), (2,2,4)))
        # 沿坐标轴旋转的角度
        self.angle_x = 0
        self.angle_y = 0
        self.angle_z = 0
        #定义求值器，设置参数uv范围，设置并激活曲面
        glMap2f(GL_MAP2_VERTEX_3, 0, 1, 0, 1, self.control_points)
        #根据函数glMap3f函数，对贝塞尔曲面的设置，启用三位坐标自动生成
        glEnable(GL_MAP2_VERTEX_3)
        
        

    def key_press(self, key, x, y):
        if key == b'a':
            self.angle_x = self.angle_x + 5
        elif key == b'z':
            self.angle_x = self.angle_x - 5
        elif key == b's':
            self.angle_y = self.angle_y + 5
        elif key == b'x':
            self.angle_y = self.angle_y - 5
        elif key == b'd':
            self.angle_z = self.angle_z + 5
        elif key == b'c':
            self.angle_z = self.angle_z - 5
    
    def draw(self):
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
        glMatrixMode(GL_MODELVIEW)
        glLoadIdentity()
        glRotate(self.angle_x, 1, 0, 0)
        glRotate(self.angle_y, 0, 1, 0)
        glRotate(self.angle_z, 0, 0, 1)
        glColor3f(0, 0, 0)
        N = 50
        #绘制两个方向的交叉曲线，构造曲面
        for j in range(N+1):
            glBegin(GL_LINE_STRIP)
            for i in range(N+1):
                #计算并绘制点
                glEvalCoord2f(i/N, j/N)
            glEnd()
            glBegin(GL_LINE_STRIP)
            for i in range(N+1):
                glEvalCoord2f(j/N, i/N)
            glEnd()
                
        
        glutSwapBuffers()

    # 消息主循环
    def mainloop(self):
        glutMainLoop()

if __name__ == '__main__':
    MyPyOpenGLTest().mainloop()
